package com.jws.jawestshow;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;

import java.io.IOException;
import java.util.List;
public class DoubleCameraActivity extends Activity {
	private static final int DISPLAY_ORIENTATION0 = 0;
	private static final int DISPLAY_ORIENTATION1 = 0;
	private Camera mCamera0,mCamera1;
	private Camera.Parameters mCameraParam0,mCameraParam1;
	private SurfaceHolder.Callback mSurfaceCallback0;
	private SurfaceHolder.Callback mSurfaceCallback1;
	private SurfaceHolder mSurfaceHolder0,mSurfaceHolder1;
	private SurfaceView mSurfaceView0,mSurfaceView1;
	private TextureView mTextureView0;
	private String mISO = "AUTO";
	private Button mButtonOpen0;
	private Button mButtonClose0;
	private Button mButtonOpen1;
	private Button mButtonClose1;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_doublecamera);
	//	initCamera0Views();
		initCamera0TextureViewViews();
		
		initCamera1Views();
		initButton();
	}
	
	private void initButton()
	{
		mButtonOpen0 = (Button) findViewById(R.id.open0);
		mButtonClose0 = (Button) findViewById(R.id.close0);
		mButtonOpen0.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (mCamera0 == null)
					return;
				mCamera0.startPreview();
				
			}
		});

		mButtonClose0.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (mCamera0 == null)
					return;
				mCamera0.stopPreview();
			}
		});

		mButtonOpen1 = (Button) findViewById(R.id.open1);
		mButtonClose1 = (Button) findViewById(R.id.close1);
		mButtonOpen1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (mCamera1 == null)
					return;
				mCamera1.startPreview();
			}
		});

		mButtonClose1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (mCamera1 == null)
					return;
				
				mCamera1.stopPreview();
			}
		});
	}
		//camera0
	class SurfaceCallback0 implements SurfaceHolder.Callback
	{
		public void surfaceChanged(SurfaceHolder paramSurfaceHolder, int paramInt1, int paramInt2, int paramInt3)
		{
			startPreview0();
		}

		public void surfaceCreated(SurfaceHolder paramSurfaceHolder)
		{
			//	openCamera0();
			try {
					mCamera0 = createCamera0(0);
            mCamera0.setPreviewDisplay(paramSurfaceHolder);
			} catch (IOException exception) {
				closeCamera0();
			}
		}

		public void surfaceDestroyed(SurfaceHolder paramSurfaceHolder)
		{
			if (mCamera0 == null)
			return;
			mCamera0.stopPreview();
			mCamera0.release();
			mCamera0 = null;
			mSurfaceHolder0 =null;
		}
	}
	TextureView0 mTextureViewCallback0;
	private void initCamera0TextureViewViews(){
		mTextureViewCallback0 = new TextureView0();
		  mTextureView0 = (TextureView)findViewById(R.id.camera_preview0);
         mTextureView0.setSurfaceTextureListener(mTextureViewCallback0);
//		 mTextureView0.setBackgroundColor(Color.BLACK);
		 mTextureView0.setOpaque(false);
	}
	
	class  TextureView0  implements TextureView.SurfaceTextureListener{

        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                      Log.i(TAG, "onSurfaceTextureAvailable: ");
					  	//	openCamera0();
			try {
					mCamera0 = createCamera0(0);
            mCamera0.setPreviewTexture(surface);
			  mCamera0.setDisplayOrientation(DISPLAY_ORIENTATION0);
			} catch (IOException exception) {
				closeCamera0();
			}
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
          Log.i(TAG, "onSurfaceTextureSizeChanged: ");
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
			          Log.i(TAG, "onSurfaceTextureDestroyed: ");
					  	if (mCamera0 == null)
					return true;
			mCamera0.stopPreview();
			mCamera0.release();
			mCamera0 = null;
		
            return true;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
         // Log.i(TAG, "onSurfaceTextureUpdated: ");
        }
    }
	  
  private void initCamera0Views()
  {
    mSurfaceCallback0 = new SurfaceCallback0();
    mSurfaceView0 = (SurfaceView)findViewById(R.id.camera_preview0);
    mSurfaceHolder0 = mSurfaceView0.getHolder();
    mSurfaceHolder0.addCallback(mSurfaceCallback0);
    mSurfaceHolder0.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  }
  
  private void openCamera0() 
  {
      if (mCamera0 == null) 
	  {
          mCamera0 = Camera.open(0);
          mCameraParam0 = mCamera0.getParameters();
     //     mCameraParam0.setFlashMode(Parameters.FLASH_MODE_ON);
          Intent intent = getIntent();
          try {
              mISO = intent.getStringExtra("ISO");
              if (TextUtils.isEmpty(mISO)) {
                  mISO = "AUTO";
              }

          } catch (Exception e) {
              mISO = "AUTO";

          }
          if (null != mCameraParam0 && null != mCamera0)
          {
              mCamera0.setParameters(mCameraParam0);
          }
      }

  }

  private void closeCamera0() {
      if (null != mCamera0) {
          mCamera0.release();
          mCamera0 = null;
      }
  }

  private void startPreview0() 
  {
      if (null != mCamera0) 
	  {
          mCameraParam0 = mCamera0.getParameters();
          Size size = mCameraParam0.getPictureSize();
          List<Size> sizes = mCameraParam0.getSupportedPreviewSizes();
          Size optimalSize = null;
          if (size != null && size.height != 0)
              optimalSize = getOptimalPreviewSize(sizes, (double) size.width / size.height);
          if (optimalSize != null) {
            //  mCameraParam0.setPreviewSize(optimalSize.width, optimalSize.height);
          }
        //  mCameraParam0.set("fps-mode", 0); 
        //  mCameraParam0.set("cam-mode", 0);
          mCamera0.setParameters(mCameraParam0);
		  mCamera0.setDisplayOrientation(DISPLAY_ORIENTATION0);

       }
  }
  String TAG = "DoubleCameraActivity";
      

 //mCamera1
  class SurfaceCallback1 implements SurfaceHolder.Callback
	{
		public void surfaceChanged(SurfaceHolder paramSurfaceHolder, int paramInt1, int paramInt2, int paramInt3)
		{
			startPreview1();
		}

		public void surfaceCreated(SurfaceHolder paramSurfaceHolder)
		{
				//openCamera1();	
			try {
				//mCamera1.setPreviewDisplay(paramSurfaceHolder);
				mCamera1 = createCamera(1);
            mCamera1.setPreviewDisplay(paramSurfaceHolder);
			
			} catch (IOException exception) {
				closeCamera1();
			}
		}

		public void surfaceDestroyed(SurfaceHolder paramSurfaceHolder)
		{
			if (mCamera1 == null)
			return;
			mCamera1.stopPreview();
			mCamera1.release();
			mCamera1 = null;
			mSurfaceHolder1 =null;
		}
	}
	 
	
	  private Camera createCamera0(int requestedCameraId) throws RuntimeException {

      //  final int requestedCameraId = requestedCameraId;
                
		Log.v("byf-camera","requestedCameraId:"+requestedCameraId);
        if (requestedCameraId == -1) {
            throw new IllegalStateException("Could not find requested camera.");
        }

        final Camera camera = Camera.open(requestedCameraId);

        if (camera == null) {
            throw new IllegalStateException("Unknown camera error.");
        }
/*
        final SizePair sizePair =
                SenseCamera.selectSizePair(camera, this.mRequestedPreviewWidth, this.mRequestedPreviewHeight);

        if (sizePair == null) {
            throw new IllegalStateException("Could not find suitable preview size.");
        }

        final Size pictureSize = sizePair.pictureSize();

        this.mPreviewSize = sizePair.previewSize();
*/
        final Camera.Parameters parameters = camera.getParameters();
/*
        if (pictureSize != null) {
            parameters.setPictureSize(mRequestedPreviewWidth, mRequestedPreviewHeight);
        }
*/
        parameters.setPreviewSize(mRequestedPreviewWidth, mRequestedPreviewHeight);
      //  parameters.setPreviewFormat(ImageFormat.FLEX_RGB_888);
		
       // camera.setDisplayOrientation(180);
      //  parameters.setRotation(180);
      //  this.setRotation(camera, parameters, requestedCameraId);

  //      if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
   //         parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
   //     }
   String flatten = parameters.flatten();
        camera.setParameters(parameters);
/*
        camera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
			Log.v(TAG,"onPreviewFrame");
            }
        });
		*/
      //  camera.addCallbackBuffer(this.createPreviewBuffer(this.mPreviewSize));

        return camera;
    }
	
	  private int mRequestedPreviewWidth = 640;
    private int mRequestedPreviewHeight = 480;
	  private Camera createCamera(int requestedCameraId) throws RuntimeException {

      //  final int requestedCameraId = requestedCameraId;
                
		Log.v("byf-camera","requestedCameraId:"+requestedCameraId);
        if (requestedCameraId == -1) {
            throw new IllegalStateException("Could not find requested camera.");
        }

        final Camera camera = Camera.open(requestedCameraId);

        if (camera == null) {
            throw new IllegalStateException("Unknown camera error.");
        }
/*
        final SizePair sizePair =
                SenseCamera.selectSizePair(camera, this.mRequestedPreviewWidth, this.mRequestedPreviewHeight);

        if (sizePair == null) {
            throw new IllegalStateException("Could not find suitable preview size.");
        }

        final Size pictureSize = sizePair.pictureSize();

        this.mPreviewSize = sizePair.previewSize();
*/
        final Camera.Parameters parameters = camera.getParameters();
/*
        if (pictureSize != null) {
            parameters.setPictureSize(mRequestedPreviewWidth, mRequestedPreviewHeight);
        }
*/
        parameters.setPreviewSize(mRequestedPreviewWidth, mRequestedPreviewHeight);
      //  parameters.setPreviewFormat(ImageFormat.YCBCR_420_888);
		
       // camera.setDisplayOrientation(180);
      //  parameters.setRotation(180);
      //  this.setRotation(camera, parameters, requestedCameraId);

  //      if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
   //         parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
   //     }
        camera.setParameters(parameters);
/*
        camera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
			Log.v(TAG,"onPreviewFrame");
            }
        });
		*/
      //  camera.addCallbackBuffer(this.createPreviewBuffer(this.mPreviewSize));

        return camera;
    }
	  
  private void initCamera1Views()
  {
    mSurfaceCallback1 = new SurfaceCallback1();
    mSurfaceView1 = (SurfaceView)findViewById(R.id.camera_preview1);
    mSurfaceHolder1 = mSurfaceView1.getHolder();
    mSurfaceHolder1.addCallback(mSurfaceCallback1);
	
    mSurfaceHolder1.setType(3);
  }
  
  private void openCamera1() 
  {
      if (mCamera1 == null) 
	  {
          mCamera1 = Camera.open(1);
          mCameraParam1 = mCamera1.getParameters();
        //  mCameraParam1.setFlashMode(Parameters.FLASH_MODE_ON);
		  mCameraParam1.setPreviewSize(mRequestedPreviewWidth, mRequestedPreviewHeight);
          Intent intent = getIntent();
          try {
              mISO = intent.getStringExtra("ISO");
              if (TextUtils.isEmpty(mISO)) {
                  mISO = "AUTO";
              }

          } catch (Exception e) {
              mISO = "AUTO";

          }
          if (null != mCameraParam1 && null != mCamera1)
          {
              mCamera1.setParameters(mCameraParam1);
          }
      }

  }

  private void closeCamera1() {
      if (null != mCamera1) {
          mCamera1.release();
          mCamera1 = null;
      }
  }

  private void startPreview1() 
  {
      if (null != mCamera1) 
	  {
          mCameraParam1 = mCamera1.getParameters();
          Size size = mCameraParam1.getPictureSize();
          List<Size> sizes = mCameraParam1.getSupportedPreviewSizes();
          Size optimalSize = null;
          if (size != null && size.height != 0)
              optimalSize = getOptimalPreviewSize(sizes, (double) size.width / size.height);
          if (optimalSize != null) {
              //mCameraParam1.setPreviewSize(optimalSize.width, optimalSize.height);
          }
          mCameraParam1.set("fps-mode", 0); 
          mCameraParam1.set("cam-mode", 0);
          mCamera1.setParameters(mCameraParam1);
		  mCamera1.setDisplayOrientation(DISPLAY_ORIENTATION1);
       }
  } 

 ////////////////////////// end mCamera1///////////////////////////////////

  

  private Camera.Size getOptimalPreviewSize(List<Size> sizes, double targetRatio)
  {
      final double ASPECT_TOLERANCE = 0.05;
      if (sizes == null) return null;
      Size optimalSize = null;
      double minDiff = Double.MAX_VALUE;
      Display display = getWindowManager().getDefaultDisplay();
      int targetHeight = Math.min(display.getHeight(), display.getWidth());
      if (targetHeight <= 0) {
          WindowManager windowManager = (WindowManager)
                  getSystemService(Context.WINDOW_SERVICE);
          targetHeight = windowManager.getDefaultDisplay().getHeight();
      }
      for (Size size : sizes) {
          if (targetHeight > size.height) continue;
          
          double ratio = (double) size.width / size.height;
          if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
          if (Math.abs(size.height - targetHeight) < minDiff) {
              optimalSize = size;
              minDiff = Math.abs(size.height - targetHeight);
          }
      }

      if (optimalSize == null) {
          for (Size size : sizes) {
              double ratio = (double) size.width / size.height;
              if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
              if (Math.abs(size.height - targetHeight) < minDiff) {
                  optimalSize = size;
                  minDiff = Math.abs(size.height - targetHeight);
              }
          }
      }

      if (optimalSize == null) {
          minDiff = Double.MAX_VALUE;
          for (Size size : sizes) {
              if (Math.abs(size.height - targetHeight) < minDiff) {
                  optimalSize = size;
                  minDiff = Math.abs(size.height - targetHeight);
              }
          }
      }
      return optimalSize;
  }
}

